#include "Character.h"
#include "CEvent.h"
#include "CSurface.h"
#include "setBehavior.h"
#include "CApp.h"

#include <vector>
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_gfxPrimitives.h>

Character::Character(Kinematic* _k){
  k = _k;
  surface = NULL;

  width = 0;
  height = 0;
  estaFrito = false;
}

void Character::OnCleanup(){
  if(this->k) delete this->k;
  if(this->surface) SDL_FreeSurface(this->surface);
}

Kinematic* Character::getKinematic() const{
  return new Kinematic(*k);
}

void Character::setKinematic(Kinematic* kine){
  if(kine){
    if(k) delete k;
    k = kine;
  }
}

void Character::update(Steering* st, long time){
  k->update(st,time);
}

Steering* Character::getSteering() const {
  Steering* ret =new Steering;
  for(int i=0, n = behaviors.size() ; i<n; i++){
    ret = behaviors[i]->getSteering();
    if (ret->linear[0] || ret->linear[1] || ret->linear[2] || ret->angular > 0.000003)
      break;
  }
  return ret;
}

void Character::updateTargetsData(){
  for(int i=0, n=behaviors.size(); i<n; i++){
    behaviors[i]->updateKinematicData();
  }
}

void Character::addSetBehavior(setBehavior* b){
  while (!behaviors.empty()){
    behaviors.pop_back();
  }
  behaviors.push_back(b);
}

void Character::OnLoop(long time){
}

bool Character::OnInit(Character* target){
  return true;
}

void Character::OnRender(SDL_Surface* display){
  int i, n;
  Node *node, *nnode;
  int widthNode = 8;
  if(theApp._flag_showGraph){
    for(i=0, n=caminoObjetivo.size(); i<n; i++){
      node = caminoObjetivo[i];
      // Pintamos el nodo
      filledEllipseRGBA(display,
          fixX((*node)[0]), fixY((*node)[1]),
          widthNode, widthNode/2,
          255, 100, 100, 128
          );
      if(i+1 < n){
        nnode = caminoObjetivo[ i+1 ];
        lineRGBA(display,
            fixX((*node)[0]), fixY((*node)[1]),
            fixX((*nnode)[0]), fixY((*nnode)[1]),
            255, 100, 100, 128
            );
      }
    }
  }
}

bool Character::isDead() const{
  return life <= 0;
}

void Character::muevete(){
  k->orientation += 1;
}

void Character::atacado(Character* c){
  life -= 10;
}

float Character::getWidth() const {
    return this->width;
}
float Character::getHeight() const {
    return this->height;
}


void Character::processYells(Kinematic *k,bool pik){
  State *aux;
  if (pik){
    aux = state->processYells(k,behaviors[PGO]);
  }else{
    aux = state->processYells(k,behaviors[PATTACKE]);
  }
  if (aux){
    delete(state);
    state = aux;
  }
}

void Character::changeToSeekPNow(){
  delete(state);
  state = new SeekPNow(behaviors[PSEEKPNOW]);
}

void Character::getFree(){
  SeekPNow* bp = dynamic_cast<SeekPNow*>(state);
  if (bp){
    delete(state);
    state = new WaitingP(behaviors[PWAITINGP]);
  }
}

void Character::addLife(int add){
  // DEBUG
//cout << "MAX LIFE " << this->max_life
//  << ", life " << this->life << endl;
  if(this->life + add > this->max_life)
    this->life = this->max_life;
  else
    this->life += add;
}

void Character::pp(){
   FNave* bp = dynamic_cast<FNave*>(state);
   if (bp){
     State *saux = ((FNave*)state)->processPlayer(behaviors[PWAITINGP]);
     delete(state);
     state= saux;
  }
}
